package org.gd.science.kttsoft;

import java.util.*;

/**
 * <pre>
 *
 * Класс для преобразования чисел из разных систем исчисления.
 *
 * Примечания:
 *
 * 1. Код алгоритма находится в методе convertNotation.
 * @see OldMathNotation#convertNotation
 *
 * 2. Можно было бы использовать char[], но для получения индекса
 * необходимо было пересать дополнительный (очень простой) метод
 * перебора. Этот метод и так реализован в коллекции ArrayList.
 * @see java.util.List
 * @see java.util.ArrayList
 *
 * 3. Можно было реализовать через Set для получения уникальных
 * значений каждого элемента, но пришлось бы дописывать код перебора
 * и поиска позиции для Set, когда такой поиск уже реализован в ArrayList
 * (поиск достаточно простой чтобы им отягащать код).
 * @see java.util.Set
 * @see java.util.TreeSet
 *
 * </pre>
 *
 * @author Gorhover D. P.
 */
@Deprecated
public class OldMathNotation {

    private static final String ALPHABET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static final List<String> ALPHABET_LIST = specialAlphabetSplit(ALPHABET);

    /**
     * General Method:
     * Method for convert Scale Notation
     *
     * @param inputString input word
     * @param inputScale input notation scale
     * @param outputScale output notation scale
     * @return output word
     */
    public static String convertNotation(String inputString, int inputScale, int outputScale) {
        List<String> input = checkArguments(inputString, inputScale);
        int sum = 0;
        int step = input.size();
        for(String item: input) {
            int attribute = (int) (Math.pow(inputScale, --step));
            sum += (ALPHABET_LIST.indexOf(item) * attribute);
        }
        if(sum < outputScale) {
            return ALPHABET_LIST.get(sum);
        }
        StringBuilder stringBuilder = new StringBuilder();
        int div;
        for(div = sum; div >= outputScale; div /= outputScale) {
            int mod = div % outputScale;
            stringBuilder.append(ALPHABET_LIST.get(mod));
        }
        stringBuilder.append(ALPHABET_LIST.get(div));
        return stringBuilder.reverse().toString();
    }

    /**
     * Secondary method:
     * special split method without duplication of characters
     *
     * @param alphabet alphabet
     * @return list of chars
     */
    private static List<String> specialAlphabetSplit(final String alphabet) {
        return new ArrayList<String>() {{
            addAll(new TreeSet<String>() {{
                addAll(Arrays.asList(alphabet.toUpperCase().split("")));
                remove("");
            }});
        }};
    }

    /**
     * Secondary method:
     * split input word to List of chars
     *
     * @param inputString input word
     * @return List of chars
     */
    private static List<String> specialSplit(final String inputString) {
        return new ArrayList<String>() {{
            addAll(Arrays.asList(inputString.toUpperCase().split("")));
            remove(0);
        }};
    }

    /**
     * Secondary method:
     * Check input arguments
     *
     * @param inputString input Word
     * @param scale input scale
     * @return list of chars
     */
    private static List<String> checkArguments(String inputString, int scale) {
        if(inputString == null || inputString.isEmpty()) {
            throw new IllegalArgumentException("inputString is empty");
        }
        List<String> unLegalAlphabet = ALPHABET_LIST.subList(0, scale);
        List<String> input = specialSplit(inputString);
        for(String item: input) {
            if(!unLegalAlphabet.contains(item)) {
                throw new IllegalArgumentException("error in input string [" + inputString + "]: not valid element [" + item + "]");
            }
        }
        return input;
    }
}
